/**
 * 
 */
package VendingMachine;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @author Xuraj
 *
 */
public class VendingMachineTest {
	
	// Initialize machine and item to test
	VendingMachine vm = null;
	VendingMachineItem item1 = null;
	VendingMachineItem item2 = null;
	VendingMachineItem item3 = null;
	VendingMachineItem item4 = null;
	
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		vm = new VendingMachine();
		item1 = new VendingMachineItem("Chips", 1.50);
		item2 = new VendingMachineItem("Pop", 1.72);
		item3 = new VendingMachineItem("Cracker", 2.0);
		item4 = new VendingMachineItem("M&M", 1.00);
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
	}

	/**
	 * Test method for {@link VendingMachine.VendingMachine#addItem(VendingMachine.VendingMachineItem, java.lang.String)}.
	 * This method will test to see if an item is added as VendingMachineItem by
	 * returning name of that item.
	 */
	@Test
	public void testAddItem() {
		vm.addItem(item1, VendingMachine.A_CODE);
		vm.addItem(item2, VendingMachine.B_CODE);
		vm.addItem(item3, VendingMachine.C_CODE);
		vm.addItem(item4, VendingMachine.D_CODE);
		assertEquals("Chips", vm.getItem(VendingMachine.A_CODE).getName());
		assertEquals("Pop", vm.getItem(VendingMachine.B_CODE).getName());
		assertEquals("Cracker", vm.getItem(VendingMachine.C_CODE).getName());
		assertEquals("M&M", vm.getItem(VendingMachine.D_CODE).getName());
	}
	
	@Test
	public void testInvalidCode() {
		vm.addItem(item1, "E");
	}
	
	@Test
	public void testOccupiedSlot() {
		vm.addItem(item4, VendingMachine.D_CODE);
		vm.addItem(item4, VendingMachine.D_CODE);
	}
	
	@Test
	public void removeEmptySlot() {
		vm.removeItem(VendingMachine.A_CODE);
		assertNull(vm.getItem(VendingMachine.A_CODE));
		
	}
	
	/**
	 * Test method for {@link VendingMachine.VendingMachine#removeItem(java.lang.String)}.
	 * This method first adds an item and then removes the item. The getItem method should
	 * return null for that slot.
	 */
	@Test
	public void testRemoveItem() {
		vm.addItem(item1, VendingMachine.A_CODE);
		vm.removeItem(VendingMachine.A_CODE);
		assertNull(vm.getItem(VendingMachine.A_CODE));
	}

	/**
	 * Test method for {@link VendingMachine.VendingMachine#insertMoney(double)}.
	 * This method adds money to the machine and then gets the balance to see if 
	 * amount is added to the machine
	 */
	@Test
	public void testInsertMoney() {
		vm.insertMoney(5.0);
		assertEquals(5.0, vm.getBalance(),0.001);
	}

	/**
	 * Test method for {@link VendingMachine.VendingMachine#getBalance()}.
	 * This method inserts money two times and checks if the balance is
	 * correct
	 */
	@Test
	public void testGetBalance() {
		vm.insertMoney(5.0);
		vm.insertMoney(1.0);
		assertEquals(6.0, vm.getBalance(),0.001);
	}

	/**
	 * Test method for {@link VendingMachine.VendingMachine#makePurchase(java.lang.String)}.
	 * This method makes purchase from a slot which should empty the slot. It checks
	 * if that slot returns null to verify the purchase.
	 */
	@Test
	public void testMakePurchase() {
		vm.addItem(item1, VendingMachine.A_CODE);
		vm.insertMoney(5.0);
		vm.makePurchase(VendingMachine.A_CODE);
		assertNull(vm.getItem(VendingMachine.A_CODE));
	}

	/**
	 * Test method for {@link VendingMachine.VendingMachine#returnChange()}.
	 * This test method adds an item and money and then makes a purchase. It then
	 * gets the balance to see if amount has been deducted from original
	 * amount after purchase.
	 */
	@Test
	public void testReturnChange() {
		vm.addItem(item1, VendingMachine.A_CODE);
		vm.insertMoney(5.0);
		vm.makePurchase(VendingMachine.A_CODE);
		assertEquals(3.50, vm.returnChange(), 0.001);
	}

}
